import { useEffect, useRef, useState } from "react";

interface WatchTimeReturn {
    elapsedTime: number;
    isMaxMinutesReached: boolean
    startTimer: () => void;
    formatTime: (ms: number) => string;
}

export const useWatchTime = (maxMin = 1): WatchTimeReturn => {
    const [elapsedTime, setElapsedTime] = useState<number>(0);
    const [isMaxMinutesReached, setIsMaxMinutesReached] = useState<boolean>(false);
    const startTimeRef = useRef<number>(Date.now());
    const animationFrameRef = useRef<number | null>(null);
    const timeLimitRef = useRef<number>(maxMin * 60 * 1000); 

    const startTimer = () => {
        // 清除现有计时器（如果正在运行）
        if (animationFrameRef.current) {
            cancelAnimationFrame(animationFrameRef.current);
        }
        // 重置计时器状态
        startTimeRef.current = Date.now();
        setElapsedTime(0);
        setIsMaxMinutesReached(false);

        // 定义更新函数
        const updateElapsedTime = () => {
            // 计算当前经过的时间
            const elapsed = Date.now() - startTimeRef.current;
            // 更新状态
            setElapsedTime(elapsed);

            /**
             * 检查是否达到时间限制
             * 如果达到: 设置完成状态并停止计时器
             * 如果未达到: 使用 requestAnimationFrame 请求下一帧更新
             */
            if (elapsed >= timeLimitRef.current) {
                setIsMaxMinutesReached(true);
                animationFrameRef.current = null;
            } else {
                animationFrameRef.current = requestAnimationFrame(updateElapsedTime);
            }
        };
        // 启动计时器循环
        animationFrameRef.current = requestAnimationFrame(updateElapsedTime);
    };

    // 初始化计时器
    useEffect(() => {
        // startTimer(); // execute time watch immediately.
        return () => {
            if (animationFrameRef.current) {
                cancelAnimationFrame(animationFrameRef.current);
            }
        };
    }, []);

    const formatTime = (ms: number): string => {
        const minutes = Math.floor(ms / 60000);
        const seconds = Math.floor((ms % 60000) / 1000);
        return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
    };

    return {
        elapsedTime,
        isMaxMinutesReached,
        startTimer,
        formatTime,
    };
};